废话不多说,记录一下命令模式的使用与定义。

定义

讲一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作,属于行为模式。

结构

UML图

UML 图中对象与对象之间的关系比较多,包括继承关系、聚合关系、关联关系。不过不必特地去记住这些关系究竟是什么。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Receiver {
constructor() {}
action() {}
}
class Command {
constructor() {}
execute() {}
}
class ConreteCommand extends Command {
constructor() {}
execute() {}
}
class Invoke {
constructor() {}
call() {}
}

时序图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
class Receiver {
constructor() {}
action1() {
console.log('我是客户要求的动作1 !');
}
action2() {
console.log('我是客户要求的动作2 !');
}
}
class Command {
constructor() {}
execute() {
console.log('必须重写该方法 !');
}
}
class ConcreteCommand extends Command {
constructor(receiver, action='') {
super();
this.receiver = receiver;
this.action = action;
}
execute() {
if (!this.receiver) {
return console.error('接受对象不能为空');
}
if (typeof this.receiver[this.action] !== 'function') {
return console.error('接收对象不存在该指令')
}
return this.receiver[this.action]();
}
}
class Invoke {
constructor() {
this.commandList = [];
}
add(command) {
if (command instanceof Command) {
this.commandList.push(command);
}
}
execute() {
for (let command of this.commandList) {
command.execute();
}
}
}
const receiver = new Receiver();
const invoke = new Invoke();
const command1 = new ConcreteCommand(receiver, 'action1');
const command2 = new ConcreteCommand(receiver, 'action2');
invoke.add(command1);
invoke.add(command2);
invoke.execute();
// 我是客户要求的动作1 !
// 我是客户要求的动作2 !

以上就是命令模式的一个简单实现。
对于调用者而言,他可以不用关心命令具体实现过程,只需要发送命令即可。
对于接受者而言,他不用在乎是谁发出了命令,只需要对于命令执行实践即可。
所以命令模式能够有效降低系统的耦合度。

图解设计模式